package com.qqtech.admin.context;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.net.HttpHeaders;
import com.qqtech.core.common.util.StringUtil;
import com.qqtech.qquan.sys.enums.SysConst;
import com.qqtech.qquan.sys.service.SysRoleService;
import com.qqtech.qquan.user.model.UserAdmin;

public class AdminInteceptor implements HandlerInterceptor {
	private static final Logger LOG = LoggerFactory.getLogger(AdminInteceptor.class);
	private static final String VK_REQUEST_ID = "vkReqId";
	private Set<String> hiddenKeys = Sets.newHashSet("password", "pwd", "authToken", "token", "base64");
	private Set<String> allowUrls;
	
	@Resource
	private SysRoleService sysRoleService;

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception arg3)
			throws Exception {
		MDC.remove(VK_REQUEST_ID);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView arg3)
			throws Exception {
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
		String uri = request.getRequestURI();
		String requestUrl = uri.replace(request.getContextPath(), "");
		if (uri.indexOf("/res/") >= 0) {
			return true;
		}
		
		if (allowUrls != null && allowUrls.contains(requestUrl)) {
			return true;
		}
		UserAdmin userAdmin = (UserAdmin) request.getSession().getAttribute(SysConst.ADMIN_USER_SESSION);
		if (userAdmin == null) {
			request.getRequestDispatcher("/user/admin/login").forward(request, response);
			return false;
		}else {
			/*if (!allowUrls.contains(uri) && !sysRoleService.checkUrl(userAdmin, uri)) {
				// 没有访问权限
				request.getRequestDispatcher(SysConst.ADMIN_ACCESS_DENIED_PAGE).forward(request, response);
				return false;
			}*/
		}
		String reqId = buildRequestId();
		MDC.put(VK_REQUEST_ID, reqId);
		printRequest(request);
		return true;
	}

	/**
	 * 生成请求id
	 * 
	 * @return
	 */
	private String buildRequestId() {
		String reqId = UUID.randomUUID().toString().replaceAll("-", "");
		return reqId;
	}

	/**
	 * 打印参数
	 *
	 * @param request
	 */
	private void printRequest(HttpServletRequest request) {
		String paramsStr = getReqParams(request);
		StringBuffer requestURL = request.getRequestURL();
		if (!Strings.isNullOrEmpty(paramsStr)) {
			requestURL.append("?" + paramsStr);
		}
		LOG.info("header={}", getHeader(request));
		LOG.info("url={}", requestURL);
	}

	@SuppressWarnings("rawtypes")
	private String getReqParams(HttpServletRequest request) {
		Map<String, String[]> map = request.getParameterMap();
		Set keSet = map.entrySet();
		StringBuffer paramStringBuffer = new StringBuffer();
		for (Iterator itr = keSet.iterator(); itr.hasNext();) {
			Map.Entry me = (Map.Entry) itr.next();
			Object key = me.getKey();
			Object v = me.getValue();
			String[] value = new String[1];
			if (v instanceof String[]) {
				value = (String[]) v;
			} else {
				value[0] = v.toString();
			}
			for (int k = 0; k < value.length; k++) {
				String str = value[k];
				if (hiddenKeys.contains(key)) {
					str = "_";
				}
				paramStringBuffer.append("&" + key + "=" + str);
			}
		}
		return paramStringBuffer.toString();
	}

	private Map<String, String> getHeader(HttpServletRequest request) {
		Map<String, String> header = Maps.newHashMap();
		header.put(HttpHeaders.REFERER, request.getHeader(HttpHeaders.REFERER));
		header.put(HttpHeaders.USER_AGENT, request.getHeader(HttpHeaders.USER_AGENT));
		header.put("VkReferer", request.getHeader("VkReferer"));
		header.put("ip", StringUtil.getClientIp(request));
		return header;
	}

	public void setAllowUrls(Set<String> allowUrls) {
		this.allowUrls = allowUrls;
	}
}
